package com.dxt.mybatislearn.mapper;

import com.dxt.mybatislearn.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Mapper
public interface EmpMapper {

    /*
     * 删除数据功能，依据传入的id进行删除
     * #{id} 是 参数id 在sql语句中的一个占位符
     * 返回值表示删除操作影响了多少行数据
     */
    @Delete("delete from emp where id = #{id}")
    public int delete(Integer id);

    /*
     * 插入数据功能
     * 方法参数是一个Emp对象，#{}内的内容与Emp对象的属性名一一对应
     * 返回值表示插入操作影响了多少条数据
     * @Options(useGeneratedKeys = true, keyProperty = "id") : 主键返回
     *    有时 执行插入后会使用到数据库为此条数据自动生成的id（自增id之类的），
     *  useGeneratedKeys = true，表明此操作会将数据库生成的id返回，
     *  keyProperty = "id"，表明 返回的id值会设置到Emp对象的id属性中
     */
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
            "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entryDate}, #{deptId}, #{createTime}, #{updateTime})")
    public Integer insert(Emp emp);

    /*
     * 更新数据功能
     * 返回值表示此次更新操作影响了多少条数据
     */
    @Update("update emp set username=#{username}, name=#{name}, image=#{image}, job=#{job}, dept_id=#{deptId}, " +
            "update_time=#{updateTime} where id=#{id}")
    public Integer update(Emp emp);


    /*
     * 根据id进行数据查询，查询到的数据会 封装 到Emp对象中，然后返回
     * 注意：
     *   如果实体类属性名 和 数据库表查询返回的字段名 一致，mybatis会进行自动封装 (大小不同 会 进行自动封装)
     *   如果实体类属性名 和 数据库表查询返回的字段名 不一致，mybatis不会进行自动封装
     * 解决方案：
     *   方案1：给字段起别名  -- 不常用
     *   方案2：使用@Results 和 @Result 注解  -- 不常用
     *   方案3：开启mybatis的驼峰命名自动映射开关 a_b ---> aB  -- 常用,只需在application.properties文件中添加配置即可
     */
    @Select("select * from emp where id = #{id}")
    public Emp getById(Integer id);
    /*
     * 方案1：给字段起别名
     */
    @Select("select id, username, password, name, gender, image, job, entryDate, " +
            "dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id}")
    public Emp getById01(Integer id);
    /*
     * 方案2：使用@Results 和 @Result 注解，
     * column: 表中字段名；property:类中属性名
     */
    @Results({
            @Result(column = "dept_id", property = "deptId"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("select * from emp where id = #{id}")
    public Emp getById02(Integer id);

    /*
     * 条件查询
     *   模糊查询名字，精确查询性别，范围查询入职时间
     * 注意：
     *   #{}出现在引号内就不表示占位符了，无法起到占位功能
     *   此时模糊查询处，不能使用#{}表示占位符，#{}可以占位一整个字符串，但不能占位字符串的一部分，
     *  %与其对应的数据组成了一个完成的字符串，此时使用${}表示数据与%的拼接
     * 注意：
     *   因为使用${}进行了字符串的拼接，所以sql语句有被注入的风险；
     *   此时可以使用concat字符串拼接方法，来完成字符串的拼接
     */
    @Select("select * from emp where name like '%${name}%' and gender = #{gender} and " +
            "entryDate between #{begin} and #{end} order by update_time desc")
    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    /*
     * 使用concat()方法 拼接字符串， 在拼接过程中可以使用 #{} 占位符
     */
    @Select("select * from emp where name like concat('%', #{name}, '%') and gender = #{gender} and " +
            "entryDate between #{begin} and #{end} order by update_time desc")
    public List<Emp> list01(String name, Short gender, LocalDate begin, LocalDate end);


    public void deleteXML(Integer id);

    public void insertXML(Emp emp);

    public void updateXML(Emp emp);

    public Emp getByIdXML(Integer id);

    //使用动态sql
    public List<Emp> listXML(String name, Short gender, LocalDate begin, LocalDate end);

    //使用动态sql -- foreach
    public void deleteByIds(List<Integer> ids);

    public Emp getIdAndName(@Param("id") Integer id);
}
